package com.zzld.modules.autoinn.action;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.ExecutionException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.zzld.core.utils.Base64Coder;
import com.zzld.core.utils.CookieUtils;
import com.zzld.core.utils.DateUtil;
import com.zzld.core.utils.OrderUtil;
import com.zzld.modules.autoinn.entity.Customer;
import com.zzld.modules.autoinn.entity.Recharge;
import com.zzld.modules.autoinn.service.ICustomerService;
import com.zzld.modules.autoinn.service.IRechargeService;
import com.zzld.modules.wechat.WeChat;
import com.zzld.modules.wechat.bean.TemplateData;
import com.zzld.modules.wechat.bean.WeChatBuyPost;
import com.zzld.modules.wechat.oauth.Message;
import com.zzld.modules.wechat.oauth.Oauth;
import com.zzld.modules.wechat.oauth.Pay;
import com.zzld.modules.wechat.util.ConfKit;
import com.zzld.modules.wechat.util.Tools;
import com.zzld.modules.wxsys.entity.WXAccount;
import com.zzld.modules.wxsys.service.IWXAccountService;

@Controller
@RequestMapping("/weixin/f/autoinn/prePay")
public class WXPrePayController {
	// 微信返回 fail 失败，success 成功
	private static final String STATUC_SUCCESS = "SUCCESS";
	private static final String STATUC_FAIL = "FAIL";

	private String prePayurl = "/wx/autoinn/prePay"; // 存款页面
	private String wxPayurl = "/wx/autoinn/wxPay"; // 支付页面
	private String rePayurl = "/wx/autoinn/relist";// 充值记录

	@Autowired
	private ICustomerService customerService;

	@Autowired
	private IRechargeService rechargeService;

	@Autowired
	private IWXAccountService wxAccountService;

	@RequestMapping(value = "re")
	public String reser(Model model, HttpServletRequest request) {
		String openid = CookieUtils.getCookie(request, "autoinn_session");
		String wxaccount = CookieUtils.getCookie(request, "wx_session");
		try {
			wxaccount = Base64Coder.decode(wxaccount);
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("wxaccount", wxaccount);
		map.put("openid", openid);
		model.addAttribute("recharge", rechargeService.selectbyrecha(map));
		return rePayurl;
	}

	@RequestMapping(method = RequestMethod.GET)
	public String wxuser(Model model, HttpServletRequest request) {
		return prePayurl;
	}

	@RequestMapping(value = "cash")
	public String cash(Model model, ModelMap modelmap,
			HttpServletRequest request) {
		// 判断是否微信环境, 5.0 之后的支持微信支付
		boolean isweixin = WeChat.isWeiXin(request);
		String openid = CookieUtils.getCookie(request, "autoinn_session");
		String wxaccount = CookieUtils.getCookie(request, "wx_session");
		try {
			if (isweixin) {
				if (StringUtils.isNotBlank(openid)
						&& StringUtils.isNotBlank(wxaccount)) {
					openid = Base64Coder.decode(openid);
					wxaccount = Base64Coder.decode(wxaccount);
					try {
						Customer entity = customerService.findCustomer(
								wxaccount, openid);
						if (entity == null) {
							modelmap.put("errormsg", "支付请求发起错误");
							return wxPayurl;
						}
						String total_fee = "1";
						// 获取充值金额
						total_fee = request.getParameter("total_fee");
						boolean isnumber = isNumber(total_fee);
						if (!isnumber) {
							modelmap.put("errormsg", "支付发起错误");
							return wxPayurl;
						}
						// 将元为单位的转换为分
						total_fee = BigDecimal.valueOf(Long.parseLong(total_fee))
								.multiply(new BigDecimal(100)).toString();
						// 获取订单号
						String orderNum = OrderUtil.generateOrderNum("YF");
						// package 参数封装----------------------------- //
						Map<String, String> params = new HashMap<String, String>();
						params.put("appid", ConfKit.get("AppId"));
						params.put("mch_id", ConfKit.get("partnerId"));
						params.put("nonce_str", RandomStringUtils.random(32,
								"abcdefghijklmnopqrstuvwxyz0123456789"));
						params.put("body", "汽车驿站充值"); // 商品描述。
						params.put("out_trade_no", orderNum); // 商户系统内部的订单号
						params.put("total_fee", total_fee); // 订单总金额
						String ip = getIp(request);// 获取ip
						params.put("spbill_create_ip", ip); // ip
						params.put("notify_url", ConfKit.get("notify_url"));
						params.put("trade_type", "JSAPI"); // 现金支付币种,取值： 1 （人民币）
						params.put("openid", openid);

						// 获取parepay_id
						try {
							String prepayid = Pay.getPrepayid(params);
							params.put("prepay_id", prepayid);
							if (prepayid != null && prepayid.length() > 10) {
								// 参数
								String timeStamp = Long.toString(new Date()
										.getTime() / 1000); // 时间戳，自1970年以来的秒数
								String nonceStr = RandomStringUtils.random(32,
										"abcdefghijklmnopqrstuvwxyz0123456789"); // 32位随机数
								String packagestring = "prepay_id=" + prepayid;
								SortedMap<String, String> nativeObj = new TreeMap<String, String>();
								nativeObj.put("appId", ConfKit.get("AppId"));
								nativeObj.put("timeStamp", timeStamp);
								nativeObj.put("nonceStr", nonceStr);
								nativeObj.put("package", packagestring);
								nativeObj.put("signType", "MD5");
								String paySign = Pay.createSign(nativeObj,
										ConfKit.get("partnerKey"));// 构造签名
								nativeObj.put("paySign", paySign);

								modelmap.put("appid", ConfKit.get("AppId"));
								modelmap.put("timeStamp", timeStamp);
								modelmap.put("nonceStr", nonceStr);
								modelmap.put("package", packagestring);
								modelmap.put("paySign", paySign);
								modelmap.put("isweixin", 1);
							}
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (ExecutionException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					modelmap.put("errormsg", "支付错误");
					return wxPayurl;
				}
			} else {
				modelmap.put("errormsg", "该版本不支持微信支付，请升级至微信5.0");
				return wxPayurl;
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		modelmap.put("errormsg", "支付错误");
		return wxPayurl;
	}

	/**
	 * 支付通知
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value = "notice")
	public void notice(HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		// post 过来的xml
		WeChatBuyPost postData = null;
		try {
			InputStream in = request.getInputStream();
			// 转换微信post过来的xml内容
			XStream xs = new XStream(new DomDriver());
			xs.alias("xml", WeChatBuyPost.class);
			String xmlMsg = Tools.inputStream2String(in);
			postData = (WeChatBuyPost) xs.fromXML(xmlMsg);
			if (postData.getReturn_code().equals("SUCCESS")
					&& postData.getResult_code().equals("SUCCESS")) {
				// 此处调用订单查询接口验证是否交易成功
				// 支付成功，商户处理后同步返回给微信参数
				// ------------------------------
				// 处理业务开始,添加充值记录,给用户余额添加金额
				// ------------------------------
				try {
					Oauth oauthInfo = new Oauth();
					WXAccount wxaccount = wxAccountService.findwxaccount(
							postData.getAppid(), oauthInfo.getSecret());
					if (wxaccount != null) {
						// 充值记录不存在则添加
						Recharge crecharge = rechargeService.selectByPrimaryKey(postData
								.getOut_trade_no());
						if (crecharge == null) {
							// 操作用户余额
							Customer entity = customerService.findCustomer(
									wxaccount.getAcccountId(),
									postData.getOpenid());

							if (entity != null) {
								BigDecimal surplus = entity.getSurplus();
								// 分转元
								BigDecimal total_fee = BigDecimal.valueOf(
										(long) postData.getTotal_fee()).divide(
										new BigDecimal(100));
								surplus = surplus.add(total_fee);
								entity.setSurplus(surplus); // 更新余额
								customerService.updateByPrimaryKeySelective(entity);

								// 更新充值记录
								Recharge recharge = new Recharge();
								recharge.setCustomer_id(entity.getCustomerId());
								recharge.setDes("汽车驿站充值");
								recharge.setId(postData.getOut_trade_no());
								recharge.setInnertime(DateUtil
										.strToDate(postData.getTime_end()));
								recharge.setPrice(total_fee);
								recharge.setWx_account(wxaccount
										.getAcccountId());
								rechargeService.save(recharge);
							}
						}
					}
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				// ------------------------------
				// 处理业务完毕
				// ------------------------------
				// 支付成功
				String noticeStr = setXML(STATUC_SUCCESS, "");
				response.getWriter().write(noticeStr);
				
				TemplateData templateData=new TemplateData(postData.getOpenid(), "S7kBjV2otDvwAEAoiehqRhXq2tyZ5rqePXno0MVD1QA");
				Message message=new Message();
				try {
					message.templateSend("",templateData);
				} catch (ExecutionException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			} else {
				// 支付失败
				String noticeStr = setXML(STATUC_FAIL, "支付失败");
				response.getWriter().write(noticeStr);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		// 支付失败
		String noticeStr = setXML(STATUC_FAIL, "支付失败");
		response.getWriter().write(noticeStr);
	}

	public static String setXML(String return_code, String return_msg) {
		return "<xml><return_code><![CDATA[" + return_code
				+ "]]></return_code><return_msg><![CDATA[" + return_msg
				+ "]]></return_msg></xml>";
	}

	/**
	 * 获取ip
	 * 
	 * @param request
	 * @return
	 */
	public static String getIp(HttpServletRequest request) {
		if (request == null)
			return "";
		String ip = request.getHeader("X-Requested-For");
		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("X-Forwarded-For");
		}
		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_CLIENT_IP");
		}
		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		String[] rip = ip.split(",");
		if (StringUtils.isNotBlank(ip) && StringUtils.isNotBlank(rip[0])) {
			ip = rip[0];
		} else {
			ip = "127.0.0.1";
		}

		return ip;
	}

	// 金额验证
	public static boolean isNumber(String str) {
		java.util.regex.Pattern pattern = java.util.regex.Pattern
				.compile("^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?$"); // 判断小数点后2位的数字的正则表达式
		java.util.regex.Matcher match = pattern.matcher(str);
		if (match.matches() == false) {
			return false;
		} else {
			return true;
		}
	}
}
